﻿
using Dapper;
using HBase;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace hCommand {
    public abstract class WcsFinshParamLocEngine<CS, CSD> :GkTransaction where CS : AbsCoreStock where CSD : AbsCoreStockDetail, new() {
        public long paramId;
        public int realStn;
        protected CoreTaskParam ctp;
        protected List<CoreTaskParam> otherCtpList;
        protected CoreTask ct;
        protected CS cs;
        protected List<CSD> hisCsdList;
        protected override TransRes Execute(IDbConnection conn ,IDbTransaction tran) {
            initData(conn ,tran);
            if( realStn != 0 ) {
                ctp.des = realStn;
            }
            finshParam(conn ,tran);
            CoreUtil.UpdataWhLoc(conn ,tran ,( int ) ctp.src ,0);//清除原货位
            long goodDiff = LocConfig.getGoodDiff(conn ,tran ,hisCsdList[0] ,cs);
            CoreUtil.UpdataWhLoc(conn ,tran ,ctp.des ,goodDiff);
            if( needFinsh(conn ,tran) ) {
                string sql = @"update core_task set Status={0},Finsh_Time=sgj_get_sys_now where  id=@id";
                sql = String.Format(sql ,( int ) CoreTaskStatus.结束);
                exec(conn ,tran ,sql ,ct);

                CsdUtil.finshStockDetail(conn ,tran ,ct ,ctp.des ,getOutDetailStatus(conn ,tran));
                exec(conn ,tran ,"update Core_stock set Status=@status   where id=@id " ,new {
                    id = ct.stockId ,
                    status = ( int ) finshStockStatus(conn ,tran)
                });

                if( LocConfig.isLoc(ctp.des) ) {
                    inFinsh(conn ,tran);
                } else {
                    outFinsh(conn ,tran);
                }

            }

            return new TransRes();
        }
        public virtual void inFinsh(IDbConnection conn ,IDbTransaction tran) {

        }
        public virtual void outFinsh(IDbConnection conn ,IDbTransaction tran) {

        }


        void finshParam(IDbConnection conn ,IDbTransaction tran) {
            string sql = @"update Core_Task_Param set  status=" + ( int ) CoreTaskParamStatus.执行完成 + " where id=@id";
            conn.Execute(sql ,new { id = paramId } ,tran);


            String lastSql = "SELECT sum([Count_Db])  FROM [core_stock_detail]  where stock_Id = @id and store_Status = " + ( int ) StockDetailStatus.库存;
            int count = conn.QueryUnique<int>(lastSql ,new { id = ct.stockId } ,tran);

            if( ctp.type != ( byte ) TaskParamType.机器人分解 ) {
                string updateSorestockSql = @"update Core_stock set  loc_Id=@stn, change_Time=sgj_get_sys_now,d_count=@count where id=@id";
                conn.Execute(updateSorestockSql ,new { id = ct.stockId ,stn = ctp.des ,count } ,tran);
                string updateDetailSql = @"update core_stock_detail set  r_loc_Id=@stn where stock_Id = @id and store_Status >" + ( int ) StockDetailStatus.删除;
                conn.Execute(updateDetailSql ,new { id = ct.stockId ,stn = ctp.des ,count } ,tran);
            } else {
                string updateSorestockSql = @"update Core_stock set   change_Time=sgj_get_sys_now,d_count=@count where id=@id";
                conn.Execute(updateSorestockSql ,new { id = ct.stockId ,count } ,tran);


            }

        }
        void initData(IDbConnection connection ,IDbTransaction transaction) {
            string paramSql = "SELECT p1.*  FROM  [Core_Task_Param] p1  join [Core_Task_Param] p2 on p1.task_Id = p2.task_Id  where p2.id = " + paramId;
            otherCtpList = connection.Query<CoreTaskParam>(paramSql ,null ,transaction).ToList();
            foreach( CoreTaskParam p in otherCtpList ) {
                if( p.id == paramId ) {
                    ctp = p;
                    otherCtpList.Remove(p);
                    break;
                }
            }
            if( ctp == null ) {
                throw new Exception("任务参数不存在" + paramId);
            }
            ct = getById<CoreTask>(ctp.taskId ,connection ,transaction);
            cs = StockUtil.getCoreStock<CS>(connection ,transaction ,ct.stockId);
            hisCsdList = CsdUtil.GetStockDetailList<CSD>(connection ,transaction ,ct.stockId);//不存在出库中的记录,否则无法入库,库外也不存在,入库扫码时需要验证
        }

        protected virtual TransRes afterFinsh(IDbConnection connection ,IDbTransaction transaction) {
            return new TransRes();
        }

        protected virtual bool needFinsh(IDbConnection connection ,IDbTransaction transaction) {
            foreach( CoreTaskParam ctp in otherCtpList ) {
                if( ctp.status < ( int ) CoreTaskParamStatus.执行完成 ) {
                    return false;
                }
            }

            return ct.des == ctp.des;
        }


        protected virtual StockStatus getOutTaskedStatus(IDbConnection connection ,IDbTransaction transaction) {
            return StockStatus.库外;
        }

        protected virtual StockDetailStatus getOutDetailStatus(IDbConnection connection ,IDbTransaction transaction) {
            return StockDetailStatus.库外;
        }
        private StockStatus finshStockStatus(IDbConnection connection ,IDbTransaction transaction) {
            if( LocConfig.isLoc(realStn) ) {
                return StockStatus.库存;
            } else {
                return getOutTaskedStatus(connection ,transaction);
            }
        }

    }
}
